package com.spring.boot.rpc.rpc07;


import com.spring.boot.rpc.rpc00.IUserService;
import com.spring.boot.rpc.rpc00.User;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;

public class Stub {

    /**
     * 改为连类都是动态的
     * @return
     */
    public static IUserService getStub(Class clazz){
        // Invocation调用，Handler处理器（方法）。
        InvocationHandler h = new InvocationHandler() {
            // 当调一个类里面的任意一个方法时，本质上是调的 invoke（代理对象，正在调哪个方法，方法传的参数）
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Socket s = new Socket("127.0.0.1", 8888);
                ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());

                String clazzName = clazz.getName();
                String methodName = method.getName();
                Class[] parametersTypes = method.getParameterTypes();
                oos.writeUTF(methodName);// 写给服务端参数名
                oos.writeObject(parametersTypes);// 参数类型
                oos.writeObject(args);// 参数

                ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
                User user = (User)ois.readObject();

                oos.close();
                s.close();
                return  user;
            }
        };
        // 参数：产生这个代理类的类加载器，当前这个代理类实现了哪些接口（IUserService接口），
        Object o = Proxy.newProxyInstance(IUserService.class.getClassLoader(), new Class[]{IUserService.class}, h);
        return (IUserService)o;
    }







//    public User findUserById(Integer id) throws IOException {
//        Socket s = new Socket("127.0.0.1", 8888);
//        ByteArrayOutputStream baos = new ByteArrayOutputStream();// 在内存里开辟一个字节数组
//        DataOutputStream dos = new DataOutputStream(baos);// 在字节数组外面套了一层DataOutputStream，用来往字节数组里写各种数据类型的
//        dos.writeInt(123);// 通过这个方法，把123变成二进制类型
//
// /*
//            baos.toByteArray()把123二进制类型转成一个真正的字节数组（int类型，所以是个4个字节的数组）
//            最后通过write 方法，把字节数组写出去，送达到服务器端
//         */
//        s.getOutputStream().write(baos.toByteArray());
//        s.getOutputStream().flush();
//
//        // 读服务端的返回值（阻塞）
//        DataInputStream dis = new DataInputStream(s.getInputStream());
//        int recvId = dis.readInt();
//        String name = dis.readUTF();
//        User user = new User(id, name);
//
//        dos.close();
//        s.close();
//        return  user;
//    }


}
